<template>
  <div class="ckeditor-container">
    <h2>CKEditor 5 编辑器 (支持HTML解析)</h2>
    <div class="editor-wrapper">
      <div ref="editorElement"></div>
    </div>

    <div class="content-preview" v-if="showPreview">
      <h3>内容预览</h3>
      <div v-html="editorData"></div>
    </div>
    
    <div class="actions">
      <el-button type="primary" @click="togglePreview">{{ showPreview ? '隐藏预览' : '显示预览' }}</el-button>
      <el-button type="success" @click="saveContent">保存内容</el-button>
      <el-button @click="clearContent">清空内容</el-button>
      <el-button type="info" @click="loadSavedContent">加载保存的内容</el-button>
      <el-button type="warning" @click="insertSampleHtml">插入示例HTML</el-button>
      <el-button type="danger" @click="parseClipboardHtml">解析剪贴板HTML</el-button>
    </div>

    <div class="html-tip">
      <h4>使用提示:</h4>
      <p><strong>方法1：直接粘贴</strong> - 复制HTML代码后，直接在编辑器中粘贴，系统会自动检测并解析</p>
      <p><strong>方法2：按钮解析</strong> - 复制HTML代码后，点击"解析剪贴板HTML"按钮进行解析</p>
      <p><strong>方法3：快捷键</strong> - 使用 Ctrl+Shift+V 快捷键解析剪贴板中的HTML代码</p>
      <p>支持单个和多个连续的HTML标签，包括颜色、字体大小、粗体、斜体、下划线等样式。</p>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'

// 使用预构建的Classic Editor包
import ClassicEditor from '@ckeditor/ckeditor5-build-classic'

const editorElement = ref(null)
let editor = null
const editorData = ref('')
const showPreview = ref(false)
const STORAGE_KEY = 'ckeditor_editor_content'

// 切换预览
const togglePreview = () => {
  showPreview.value = !showPreview.value
  if (showPreview.value) {
    editorData.value = editor.getData()
  }
}

// 保存内容到本地存储
const saveContent = () => {
  if (editor) {
    const content = editor.getData()
    localStorage.setItem(STORAGE_KEY, content)
    ElMessage.success('内容已保存')
  }
}

// 加载保存的内容
const loadSavedContent = () => {
  const savedContent = localStorage.getItem(STORAGE_KEY)
  if (savedContent && editor) {
    editor.setData(savedContent)
    ElMessage.success('已加载保存的内容')
  } else {
    ElMessage.warning('没有找到保存的内容')
  }
}

// 清空编辑器内容
const clearContent = () => {
  if (!editor) return
  
  ElMessageBox.confirm('确定要清空编辑器内容吗?', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(() => {
    editor.setData('')
    editorData.value = ''
    ElMessage.success('内容已清空')
  }).catch(() => {
    // 取消操作
  })
}

// 插入示例HTML内容
const insertSampleHtml = () => {
  if (!editor) return
  
  const sampleHtml = `
    <p style="font-weight: bold; text-decoration: underline; color: #ff4757;">
      这是一段加粗、带下划线且红色的文本
    </p>
    <p style="font-size: 20px; color: #5352ed;">
      这是一段20px大小的蓝色文字
    </p>
    <p style="background-color: #ffa502; padding: 10px; border-radius: 5px;">
      这是一段有黄色背景的文字
    </p>
    <div style="border: 2px solid #2ed573; padding: 15px; margin: 10px 0;">
      <h3 style="color: #2ed573; margin: 0 0 10px 0;">带边框的区域</h3>
      <p style="margin: 0;">这是一个带绿色边框的div容器</p>
    </div>
  `
  
  // 获取当前内容并添加新内容
  const currentData = editor.getData()
  editor.setData(currentData + sampleHtml)
  ElMessage.success('已插入示例HTML内容')
}

// 手动解析剪贴板HTML
const parseClipboardHtml = async () => {
  try {
    const clipboardText = await navigator.clipboard.readText()
    
    if (!clipboardText) {
      ElMessage.warning('剪贴板为空')
      return
    }
    
    if (!clipboardText.includes('<') || !clipboardText.includes('>')) {
      ElMessage.warning('剪贴板中没有HTML代码')
      return
    }
    
    const processedHtml = processRawHtmlCode(clipboardText)
    const currentContent = editor.getData()
    editor.setData(currentContent + processedHtml)
    
    ElMessage.success('剪贴板HTML已解析并插入！')
  } catch (error) {
    console.error('读取剪贴板失败:', error)
    ElMessage.error('读取剪贴板失败，请手动复制粘贴')
  }
}

// 自定义HTML粘贴处理函数
const setupHtmlPasteHandler = () => {
  if (!editor) return

  // 监听粘贴事件
  editor.editing.view.document.on('clipboardInput', (evt, data) => {
    // 获取粘贴的数据
    const dataTransfer = data.dataTransfer
    const htmlData = dataTransfer.getData('text/html')
    const textData = dataTransfer.getData('text/plain')
    
    // 检查是否是HTML代码（包含HTML标签）
    const isHtmlCode = textData && textData.includes('<') && textData.includes('>')
    
    if (isHtmlCode) {
      // 阻止默认粘贴行为
      evt.stop()
      
      try {
        // 处理HTML代码
        const cleanHtml = processRawHtmlCode(textData)
        
        // 插入处理后的HTML
        editor.model.change(writer => {
          const selection = editor.model.document.selection
          const position = selection.getFirstPosition()
          
          // 使用setData临时方法插入HTML
          const currentContent = editor.getData()
          editor.setData(currentContent + cleanHtml)
        })
        
        ElMessage.success('HTML代码已解析并插入！')
      } catch (error) {
        console.error('HTML解析失败:', error)
        ElMessage.error('HTML解析失败，请检查代码格式')
      }
    }
  }, { priority: 'high' })
}

// 处理原始HTML代码
const processRawHtmlCode = (htmlCode) => {
  try {
    // 创建临时DOM来解析HTML
    const tempContainer = document.createElement('div')
    tempContainer.innerHTML = htmlCode.trim()
    
    // 递归处理所有元素
    const processElement = (element) => {
      if (element.nodeType === Node.TEXT_NODE) {
        return element.textContent
      }
      
      if (element.nodeType === Node.ELEMENT_NODE) {
        const tagName = element.tagName.toLowerCase()
        const attributes = Array.from(element.attributes)
        const children = Array.from(element.childNodes)
        
        // 构建属性字符串
        let attrString = ''
        attributes.forEach(attr => {
          attrString += ` ${attr.name}="${attr.value}"`
        })
        
        // 处理子元素
        const childContent = children.map(child => processElement(child)).join('')
        
        // 返回完整的HTML标签
        if (childContent) {
          return `<${tagName}${attrString}>${childContent}</${tagName}>`
        } else {
          return `<${tagName}${attrString}></${tagName}>`
        }
      }
      
      return ''
    }
    
    // 处理所有子元素
    const result = Array.from(tempContainer.childNodes)
      .map(child => processElement(child))
      .join('')
    
    return result
  } catch (error) {
    console.error('HTML处理错误:', error)
    return htmlCode // 如果处理失败，返回原始代码
  }
}

// 添加键盘快捷键支持
const setupKeyboardShortcuts = () => {
  if (!editor) return
  
  editor.keystrokes.set('Ctrl+Shift+V', (evt, cancel) => {
    // 特殊粘贴处理
    navigator.clipboard.readText().then(text => {
      if (text.includes('<') && text.includes('>')) {
        const processed = processRawHtmlCode(text)
        const currentContent = editor.getData()
        editor.setData(currentContent + processed)
        ElMessage.success('HTML代码已通过快捷键解析！')
      }
    }).catch(err => {
      console.error('读取剪贴板失败:', err)
    })
    
    cancel()
  })
}

onMounted(async () => {
  try {
    // 初始化编辑器
    editor = await ClassicEditor.create(editorElement.value, {
      toolbar: [
        'heading',
        '|',
        'bold',
        'italic',
        'link',
        'bulletedList',
        'numberedList',
        '|',
        'outdent',
        'indent',
        '|',
        'imageUpload',
        'blockQuote',
        'insertTable',
        '|',
        'undo',
        'redo'
      ],
      language: 'zh-cn'
    })

    // 添加数据变化监听
    editor.model.document.on('change:data', () => {
      editorData.value = editor.getData()
    })

    // 设置HTML粘贴处理函数
    setupHtmlPasteHandler()

    // 设置键盘快捷键支持
    setupKeyboardShortcuts()

    // 检查是否有保存的内容
    const savedContent = localStorage.getItem(STORAGE_KEY)
    if (savedContent) {
      editor.setData(savedContent)
      ElMessage.info('已加载上次保存的内容')
    } else {
      editor.setData(`
        <h2>欢迎使用 CKEditor 5 编辑器！</h2>
        <p>此编辑器支持直接解析HTML内容，你可以：</p>
        <ul>
          <li>直接复制包含样式的HTML内容</li>
          <li>使用工具栏添加各种格式</li>
          <li>支持基本的文本样式和格式</li>
        </ul>
        <p><strong>试试复制一些带样式的HTML内容到这里！</strong></p>
      `)
    }
  } catch (error) {
    console.error('初始化CKEditor失败:', error)
    ElMessage.error('初始化编辑器失败: ' + error.message)
  }
})

onBeforeUnmount(() => {
  // 销毁编辑器
  if (editor) {
    editor.destroy()
    editor = null
  }
})
</script>

<style>
.ckeditor-container {
  max-width: 1000px;
  margin: 20px auto;
  padding: 20px;
}

.editor-wrapper {
  margin-bottom: 20px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
}

.content-preview {
  margin-top: 30px;
  padding: 15px;
  border: 1px dashed #dcdfe6;
  border-radius: 4px;
  background-color: #f9f9f9;
}

.actions {
  margin-top: 20px;
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

.html-tip {
  margin-top: 30px;
  padding: 15px;
  background-color: #e8f4fd;
  border-left: 4px solid #409eff;
  border-radius: 4px;
}

.html-tip h4 {
  margin: 0 0 10px 0;
  color: #409eff;
}

.html-tip p {
  margin: 5px 0;
  color: #606266;
}

/* CKEditor样式调整 */
.ck-editor__editable {
  min-height: 400px;
}

.ck-content {
  font-size: 16px;
}

/* 确保编辑器内的样式能正确显示 */
.ck-content p {
  margin: 0.5em 0;
}

.ck-content div {
  display: block;
}

/* 支持自定义样式 */
.ck-content [style] {
  /* 允许内联样式 */
}
</style> 